<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>

        body {
            display: flex;
        }

    </style>
</head>
<body style="margin-top: 500px;">
    <div class="box1"
         style=" line-height: 51px; position: relative; height: 51px; border-radius: 5px;
                 background: #333; margin-inline: 10px;
                "
    ><span style="font-size: 48px; color: white" >&af;&af; → &af;&af;</span>
        <div class="xbox1" style="height: 50px;background: rgba(133, 93, 106, 1);position: absolute; bottom: 0"></div>
        <div class="xbox2" style="height: 0; width: 500px; background: rgba(241,6,84,0.5);position: absolute; bottom: 51px"></div>
    </div>
</body>
<script>

    const obox1 = document.querySelector(".box1");
    const oxbox1 = document.querySelector(".xbox1");
    const oxbox2 = document.querySelector(".xbox2");

    obox1.onclick = function () {
        move(oxbox1, {
            width: 500,
            height: 51
        }, function () {
            move(oxbox2, {
                width: 500,
                height: 240
            })
        });
    }

    function move(ele, obj, callback) {
        clearInterval(ele.time);
        ele.time = setInterval(() => {
            let flag = true;
            for (let objKey in obj) {
                let now = parseInt(getStyle(ele, objKey));
                let speed = (obj[objKey] - now) / 10;
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                ele.style[objKey] = now + speed + "px";
                if (now !== obj[objKey]) {
                    flag = false
                }
            }
            if (flag) {
                clearInterval(ele.time);
                callback && callback()
            }
        }, 30);
    }

    function getStyle(ele, attr) {
        if (getComputedStyle) {
            return getComputedStyle(ele)[attr];
        } else {
            return ele.currentStyle[attr];
        }
    }


</script>
</html>